package com.com.knowledgepaymentmanagementsystem.aop;

import com.alibaba.fastjson.JSONObject;
import com.com.knowledgepaymentmanagementsystem.mapper.log.OperateLogMapper;
import com.com.knowledgepaymentmanagementsystem.pojo.Log.OperateLog;
import com.com.knowledgepaymentmanagementsystem.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Arrays;

/**
 * @author 张攀
 * @version 1.0
 * @description: TODO
 * @date 2025/9/23 下午9:31
 */

@Slf4j
@Component
@Aspect
public class LogAspect {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private OperateLogMapper operateLogMapper;

    @Around("@annotation(com.com.knowledgepaymentmanagementsystem.anno.Log)")
    public Object recordLog(ProceedingJoinPoint joinPoint) throws Throwable {

        //获取请求头中的jwt令牌，解析令牌
        String jwt = request.getHeader("token");
        Claims claims = JwtUtils.parseJWT(jwt);
        String operateUser = (String) claims.get("account");

        //操作时间
        LocalDateTime operateTime = LocalDateTime.now();

        //获取操作的类名
        String className = joinPoint.getTarget().getClass().getName();

        //操作方法
        String methodsName = joinPoint.getSignature().getName();

        //操作的方法名
        Object[] args = joinPoint.getArgs();
        String methodParams = Arrays.toString(args);

        //时间
        Long begin = System.currentTimeMillis();

        //开始方法记录时间
        Object result = joinPoint.proceed();

        //终止时间
        Long end = System.currentTimeMillis();

        //方法的返回值
        String returnValue = JSONObject.toJSONString(result);
        //操作耗时
        Long costTime = end - begin;

        //记录操作日志
        OperateLog operateLog = new OperateLog(null,operateUser,operateTime,className,methodsName,methodParams,returnValue,costTime);
        operateLogMapper.insert(operateLog);

        log.info("AOP记录日志" + operateLog);
        return result;
    }
}
